package com.gxc.async;

import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import javax.annotation.Resource;
import java.util.concurrent.Callable;

/**
 * @author GongXincheng
 * @since 2019-10-13 00:24
 */
@RestController
public class AsyncController {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Resource
    private MockQueue mockQueue;

    @Resource
    private DeferredResultHolder deferredResultHolder;

    /**
     * 主线程
     */
    @GetMapping("/order1")
    public String order() throws InterruptedException {
        log.info("主线程开始");
        Thread.sleep(1000L);
        log.info("主线程返回");
        return "success";
    }

    /**
     * 使用Runnable方式异步
     */
    @GetMapping("/order2")
    public Callable<String> order2() {
        log.info("主线程开始");
        // 开启副线程
        Callable<String> callable = () -> {
            log.info("副线程开始");
            Thread.sleep(1000L);
            log.info("副线程返回");
            return "success";
        };
        log.info("主线程返回");
        return callable;
    }

    /**
     * 使用 DeferredResult 方式异步
     */
    @GetMapping("/order3")
    public DeferredResult<String> order3() throws Exception {
        log.info("主线程开始");

        // 下单
        String orderNum = RandomStringUtils.randomNumeric(8);
        mockQueue.setPlaceOrder(orderNum);

        DeferredResult<String> result = new DeferredResult<>();
        deferredResultHolder.getMap().put(orderNum, result);

        log.info("主线程返回");
        return result;
    }


}
